package com.kehutong.contact.service;

import com.kehutong.contact.entity.ResidentCar;
import com.kehutong.contact.entity.ResidentHouse;
import com.kehutong.contact.enums.BindType;
import org.coraframework.bean.Beans;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.http.Bean;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.execute.entity.FindArray;
import org.coraframework.util.Objects;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@WebService("/crm/resident/car/service")
public class ResidentCarService {
    static final Logger logger = LoggerFactory.getLogger(ResidentCarService.class);

    @Inject
    private JdbcSession jdbcSession;

    @Inject
    private ResidentAssetsService residentAssetsService;

    /**
     * 根据条件获取住户汽车列表
     *
     * @param jsonObject 查询对象
     * @return 住户汽车列表
     * @throws IOException 操作异常
     */
    @ReqMapping("/page")
    public Page<ResidentCar> page(JSONObject jsonObject) throws Exception {
        Page<ResidentCar> result = null;
        result = jdbcSession.findPage(ResidentCar.class)
                .eq(jsonObject, "id", "residentNo", "carNo", "parkingNo")
                .eq("deleted", 0)
                .like(jsonObject, "carBrand", "carModel", "carClor")
                .order("createTime", "desc")
                .page(jsonObject).exe();
        if (logger.isDebugEnabled()) {
            logger.debug("result:" + result);
        }

        if (Objects.nonNull(result)) {
            List<ResidentCar> carList = result.getList();
            for (ResidentCar residentCar : carList) {
                buildResidentCarOtherData(residentCar);
            }
        }

        return result;
    }

    /**
     * 构建车辆额外数据
     * @param residentCar
     */
    public void buildResidentCarOtherData(ResidentCar residentCar) {
        //获取车辆的业主房屋,业主车位
        ResidentHouse ownerHouse = residentAssetsService.getHouseOwner(residentCar.getHouseNo());
        if (Objects.nonNull(ownerHouse)) {
            residentCar.setHouseName(residentAssetsService.getFullHouseName(ownerHouse));
        }
        ResidentHouse ownerParking = residentAssetsService.getHouseOwner(residentCar.getParkingNo());
        if (Objects.nonNull(ownerParking)) {
            residentCar.setParkingName(residentAssetsService.getFullHouseName(ownerParking));
            residentCar.setBindType(ownerParking.getBindType());
            residentCar.setBindTime(ownerParking.getBindTime());
            residentCar.setUnBindTime(ownerParking.getUnBindTime());
        }
    }


    @ReqMapping("/list")
    public Object list(JSONObject jsonObject) {
        return jdbcSession.findArray(ResidentCar.class)
                .eq(jsonObject, "id","residentNo")
                .like(jsonObject, "carNo", "carModel", "carColor")
                .eq("deleted", false)
                .exe();
    }

    @ReqMapping("/get")
    public Object get(ResidentCar residentCar) {
        return residentCar;
    }

    /**
     * 校验住户房屋绑定唯一性
     * 一个房子只能有一个有效(待绑定,已绑定)业主记录
     * 一个房子只能只能有一条有效(待绑定,已绑定)租客或家属记录
     */
    private void checkResidentHouseUnique(ResidentCar residentCar) {
        if (Objects.isEmpty(residentCar.getParkingNo())) {
            throw new RuntimeException("车位不能为空.");
        }
        if (Objects.isEmpty(residentCar.getResidentNo())) {
            throw new RuntimeException("住户编号不能为空.");
        }
        if (Objects.isNull(residentCar.getCarNo())) {
            throw new RuntimeException("车牌不能为空.");
        }

        List<ResidentCar> parkingCarList = jdbcSession.findArray(ResidentCar.class)
                .eq("parkingNo", residentCar.getParkingNo())
                .noEq("carNo", residentCar.getCarNo())
                .eq("deleted", false)
                .exe();

        if (Objects.nonEmpty(parkingCarList)) {
            throw new RuntimeException("当前车位已经被其他车辆锁定.");
        }



        List<String> bindTypeList = new ArrayList<>();
        bindTypeList.add(BindType.NO_BIND.getId());
        bindTypeList.add(BindType.BIND.getId());
        FindArray<ResidentCar> find = jdbcSession.findArray(ResidentCar.class)
                .eq("parkingNo", residentCar.getParkingNo())
                .in("bindType", bindTypeList)
                .eq("deleted", false);
        List<ResidentCar> residentCarList = find.exe();
        if (Objects.nonEmpty(residentCarList)) {
            ResidentCar dbResidentCar = residentCarList.get(0);
            if (Objects.equal(residentCar.getResidentNo(), dbResidentCar.getResidentNo())) {
                if (Objects.equal(residentCar.getCarNo(), dbResidentCar.getCarNo())) {
                    throw new RuntimeException("不允许重复新增");
                } else {
                    throw new RuntimeException("车位" + residentCar.getParkingNo() + "已经被您的另外一台车辆锁定");
                }

            } else {
                throw new RuntimeException("车位" + residentCar.getParkingNo() + "已经被其业主车辆锁定");
            }
        }
    }

    private void checkSave(ResidentCar residentCar) {
        if (Objects.isEmpty(residentCar.getResidentNo())) {
            throw new RuntimeException("住户编号不能为空.");
        }
        if (Objects.isNull(residentCar.getCarNo())) {
            throw new RuntimeException("车牌不能为空.");
        }


        ResidentCar isExistCar = jdbcSession.findOne(ResidentCar.class)
                .eq("carNo",residentCar.getCarNo())
                .eq("deleted", false)
                .exe();
        if(Objects.nonNull(isExistCar)){
            throw new RuntimeException("车牌已经存在.");
        }
        if(Objects.nonEmpty(residentCar.getParkingNo())){
            List<ResidentCar> parkingCarList = jdbcSession.findArray(ResidentCar.class)
                    .eq("parkingNo", residentCar.getParkingNo())
                    .noEq("carNo", residentCar.getCarNo())
                    .eq("deleted", false)
                    .exe();

            if (Objects.nonEmpty(parkingCarList)) {
                throw new RuntimeException("当前车位已经被其他车辆锁定.");
            }
        }
    }

    private void checkUpdate(ResidentCar residentCar) {
        if (Objects.isEmpty(residentCar.getParkingNo())) {
            throw new RuntimeException("车位不能为空.");
        }
        if (Objects.isEmpty(residentCar.getResidentNo())) {
            throw new RuntimeException("住户编号不能为空.");
        }
        if (Objects.isNull(residentCar.getCarNo())) {
            throw new RuntimeException("车牌不能为空.");
        }


        ResidentCar isExistCar = jdbcSession.findOne(ResidentCar.class)
                .noEq("id", residentCar.getId())
                .eq("carNo",residentCar.getCarNo())
                .eq("deleted", false)
                .exe();
        if(Objects.nonNull(isExistCar)){
            throw new RuntimeException("车牌已经存在.");
        }
        if(Objects.nonEmpty(residentCar.getParkingNo())){
            List<ResidentCar> parkingCarList = jdbcSession.findArray(ResidentCar.class)
                    .eq("parkingNo", residentCar.getParkingNo())
                    .noEq("id",residentCar.getId())
                    .eq("deleted", false)
                    .exe();

            if (Objects.nonEmpty(parkingCarList)) {
                throw new RuntimeException("当前车位已经被其他车辆锁定.");
            }
        }
    }
    @Bean(newInstance = true, copy = true)
    @ReqMapping("/save")
    public Object save(ResidentCar residentCar) {
        checkSave(residentCar);
        jdbcSession.insert(residentCar);
        return Result.success();
    }

    @Bean(copy = true)
    @ReqMapping("/update")
    public Object update(ResidentCar residentCar) throws Exception {
        checkUpdate(residentCar);
        jdbcSession.updateById(residentCar);
        return Result.success();
    }

    @ReqMapping("/delete")
    public Object delete(ResidentCar residentCar) {
        residentCar.setDeleted(true);
        jdbcSession.updateById(residentCar);
        return Result.success();
    }

    /**
     * 根据车位编号获取已绑定的车位住户车辆信息
     *
     * @return 住户车辆绑定信息
     */
    private ResidentCar getBindResidentCarByParkingNo(String parkingNo) {
        return jdbcSession.findOne(ResidentCar.class)
                .eq("stationNo", parkingNo)
                .eq("bindType", BindType.BIND)
                .eq("deleted", false)
                .exe();
    }


    /**
     * 根据车位编号获取待绑定的车位住户车辆信息
     *
     * @return 住户车辆绑定信息
     */
    private ResidentCar getNoBindResidentCarByParkingNo(String parkingNo) {
        return jdbcSession.findOne(ResidentCar.class)
                .eq("stationNo", parkingNo)
                .eq("bindType", BindType.NO_BIND)
                .eq("deleted", false)
                .exe();
    }

    /**
     * 批量新增或更新住户车辆绑定信息
     * 1.如果车位已经被小程序认证审核通过则忽略当前数据
     * 2.车位没有被占用直接新增
     * 3.车位已经被其他住户占解绑,然后新增
     * 4.车位已经被自己占用,新增车牌与自己占用的车牌不一致,进行解绑新增
     * 5.车位已经被自己占用,新增车牌与自己占用的车牌不一致,进行解绑新增
     *
     * @param condition 数据对象
     * @return 成功结果
     */
    @ReqMapping("/batchSaveOwnerCar")
    public Object batchSaveOrUpdateResidentCar(JSONObject condition) throws Exception {
        JSONArray ownerCarList = condition.getJSONArray("ownerList");
        if (Objects.nonEmpty(ownerCarList)) {
            for (int i = 0; i < ownerCarList.size(); i++) {
                JSONObject ownerCarJson = ownerCarList.getJSONObject(i);
                ResidentCar residentCar = Pool.newInstance(ResidentCar.class);
                Beans.from(ownerCarJson).to(residentCar).igornNull().copy();

                //如果车位已经被小程序认证审核通过则忽略当前数据
                ResidentCar bindResidentCar = getBindResidentCarByParkingNo(residentCar.getParkingNo());
                if (Objects.nonNull(bindResidentCar)) {
                    continue;
                }
                saveOrUpdateResidentCar(residentCar);
            }
        }
        return Result.success();
    }

    /**
     * 新增或更新住户绑定信息
     * <p>
     * <p>
     * 1.车位已绑定不能新增,抛异常
     * 2.车位没有被占用直接新增
     * 3.车位已经被其他住户占解绑,然后新增
     * 4.车位已经被自己占用,新增车牌与自己占用的车牌不一致,进行解绑新增
     * 5.车位已经被自己占用,新增车牌与自己占用的车牌不一致,进行解绑新增
     *
     * @param residentCar 住户车辆
     * @return <code>true</code> 成功 <code>false</code>失败
     * @throws Exception 异常
     * @throws Exception 异常
     */
    @ReqMapping("/saveOrUpdateResidentCar")
    public Object saveOrUpdateResidentCar(ResidentCar residentCar) throws Exception {
        //编号
        String id = residentCar.getId();
        if(Objects.nonEmpty(residentCar.getParkingNo())){
            //如果当前固定车位已经被其他车辆占用,则解绑其他车辆占用的车位.
            List<ResidentCar> parkingCarList = jdbcSession.findArray(ResidentCar.class)
                    .eq("parkingNo", residentCar.getParkingNo())
                    .noEq("carNo", residentCar.getCarNo())
                    .eq("deleted", false)
                    .exe();
            if (Objects.nonEmpty(parkingCarList)) {
                ResidentCar parkingCar = parkingCarList.get(0);
                parkingCar.setParkingNo("");
                jdbcSession.updateById(parkingCar);
            }
        }

        ResidentCar isExistData = Pool.get(ResidentCar.class, id);
        if (Objects.isNull(isExistData)) {
            return save(residentCar);
        } else {
            return update(residentCar);
        }
    }
}
